package com.tricky.tron.trc20.component;

import com.alibaba.fastjson.JSON;
import com.tricky.tron.trc20.common.Deposit;
import com.tricky.tron.trc20.entity.Account;
import com.tricky.tron.trc20.event.DepositEvent;
import com.tricky.tron.trc20.service.AccountService;
import com.tricky.tron.trc20.service.Trc20Service;
import lombok.Data;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

@Data
public  class Watcher implements Runnable {
    private Logger logger = LoggerFactory.getLogger(Watcher.class);
    @Autowired
    private AccountService accountService;
    @Autowired
    private Trc20Service trc20Service;
    @Value("${tron.contract-address}")
    private String contractAddress;//hex格式

    @Value("${tron.address}")
    private String address;//发币地址 hex格式

    @Value("${tron.private-key}")
    private String privateKey;//私钥
    private boolean stop = false;
    //默认同步间隔20秒
    private Long checkInterval = 2000L;
    private Long currentBlockHeight = 0L;
    private int step = 5;
    private DepositEvent depositEvent;

    public void check() {
        try {
            //获取所有的账户
            List<Account> accountList = accountService.findAll();
            List<Deposit> depositList = this.transferToOwner(accountList);
            if (!CollectionUtils.isEmpty(depositList)) {
                depositList.forEach(deposit -> {
                    depositEvent.onConfirmed(deposit);
                });
            } else {
                logger.info("{} 充值记录为空",new Date());
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public  List<Deposit> transferToOwner(List<Account> accountList){
        if(!CollectionUtils.isEmpty(accountList)){
           List<Deposit> depositList = new ArrayList<>();
           accountList.stream().forEach(account -> {
               BigInteger contractBalance = trc20Service.balanceOf(contractAddress,account.getAddress());
               if(contractBalance.compareTo(new BigInteger("0"))>0){
                   String txId = trc20Service.sendTokenTransaction(contractAddress,account.getAddress(),account.getPrivateKey(),contractBalance.toString(),address,"转入本公司账户");
                   if(!StringUtils.isEmpty(txId)){
                       Deposit deposit = new Deposit();
                       deposit.setTxid(txId);
                       deposit.setAddress(account.getAddress());
                       deposit.setAmount(new BigDecimal(contractBalance));
                       deposit.setTime(Calendar.getInstance().getTime());
                       depositList.add(deposit);
                   }

               }
           });
           return depositList;
        }else{
            return null;
        }

    }

    @Override
    public void run() {
        stop = false;
        long nextCheck = 0;
        while (!(Thread.interrupted() || stop)) {
            if (nextCheck <= System.currentTimeMillis()) {
                try {
                    nextCheck = System.currentTimeMillis() + checkInterval;
                    logger.info("check...");
                    check();
                } catch (Exception ex) {
                    logger.info(ex.getMessage());
                }
            } else {
                try {
                    Thread.sleep(Math.max(nextCheck - System.currentTimeMillis(), 100));
                } catch (InterruptedException ex) {
                    logger.info(ex.getMessage());
                }
            }
        }
    }
}
